--[[--
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
                         ^                                      ^
    0: now, times=0
    1: 10 times after, times=0
    2: 14 times after, times=0
]]
local Feeder = {}

local DEBUG = false

local IO_MOTOR = 5

local feedTimes_ = 0
local times_ = 0
local nowCheck_ = 1
local checkTimes_ = {10, 14}
local checkTimer_ = nil
local motorTimer_ = nil
local isFeeding_ = false

local checkDelay_ = 1000 -- 1s
local motorDownDelay_ = 5000 -- 5s

local function onMotorTimer()
    if DEBUG then
        print("motor down")
    end
    gpio.write(IO_MOTOR, gpio.LOW)
    isFeeding_ = false
end

local function feed()
    if DEBUG then
        print("feed")
    end
    if not motorTimer_ then
        motorTimer_ = tmr.create()
    end
    isFeeding_ = true
    gpio.write(IO_MOTOR, gpio.HIGH)
    feedTimes_ = feedTimes_ + 1
    motorTimer_:alarm(motorDownDelay_, tmr.ALARM_SINGLE, onMotorTimer)
end

local function onTimer()
    if _G["kill_feeder_timer"] then
        Feeder.stop()
        _G["kill_feeder_timer"] = nil
        return
    end
    times_ = times_ + 1
    if DEBUG then
        print("times:" .. times_)
    end
    if times_ >= checkTimes_[nowCheck_] then
        feed()
        times_ = 0
        nowCheck_ = nowCheck_ + 1
        if nowCheck_ > #checkTimes_ then
            nowCheck_ = 1
        end
    end
end

function Feeder.start()
    feedTimes_ = 0
    times_ = 0
    nowCheck_ = 1
    checkTimer_ = tmr.create()
    checkTimer_:alarm(checkDelay_, tmr.ALARM_AUTO, onTimer)
    if DEBUG then
        print("feeder start")
    end
    feed()
    onTimer()
end

function Feeder.stop()
    if Feeder.isRunning() then
        checkTimer_:stop()
        checkTimer_ = nil
        if motorTimer_ then
            motorTimer_:stop()
            motorTimer_ = nil
        end
        onMotorTimer()
        if DEBUG then
            print("feeder stop")
        end
    end
end

function Feeder.feed()
    if not isFeeding_ then
        feed()
    end
end

function Feeder.getFeedTimes()
    return feedTimes_
end

function Feeder.isRunning()
    return checkTimer_ ~= nil
end

function Feeder.init(checkDelay, motorDownDelay)
    checkDelay_ = checkDelay or 1000
    motorDownDelay_ = motorDownDelay or 2000

    gpio.mode(IO_MOTOR, gpio.OUTPUT)
    gpio.write(IO_MOTOR, gpio.LOW)
end

return Feeder
